import $ from '@/axios';
import deepClone from '@/utils/clone';
import { Notification } from 'element-ui';

import { msgError } from '@/utils/message';

import FileSaver from 'file-saver';

import store from '@/store';
import { compare } from '@/utils/util';

let _heartbeatTimer = null;
let _pollTimer = null;
let _videoMap = null;
let _videoGroupMap = null;
let _operatorList = null;
let _operatorTelMap = new Map();
let _employeeList = null;
let _employeeTelMap = new Map();

let _userStatusMap = new Map();

class SDK {
  constructor(options) {
    // this.username = options.username;
    // this.password = options.password;
    this.isPoll = true;
    this.pollInterval = 1000;
    this.heartbeatInterval = 10000;
    this.event = null;
    //
    this.haveNewSms = false;
    this.haveNewSmsKeepFresh = false;
    this.navKey = 1;
    postConstruct.call(this, options);
  }
  /**
   * 初始化
   * @param {Fuction} event 回调事件
   * @param {Object} options 配置选项
   */
  init(options, event) {
    // 是否开启轮询 true开启
    if (options.isPoll) this.isPoll = options.isPoll;
    if (options.pollInterval) this.pollInterval = options.pollInterval;
    if (options.heartbeatInterval)
      this.heartbeatInterval = options.heartbeatInterval;
    if (event) this.event = event;
  }

  /**
   * 获取操作员信息
   */
  getOperatorInfo() {
    return this.operatorInfo;
  }

  /**
   * 获取号码状态
   */
  userStatus() {
    return new Promise((resolve, reject) => {
      $.post('/userstatus', { deviceTel: 'all' })
        .then(res => {
          res = res.data;
          resolve(res);
        })
        .catch(err => reject(err));
    });
  }

  /**
   * 获取号码状态
   */
  getTelStatus(tel) {
    const user = _userStatusMap.get(tel);
    return user ? user.deviceStatus : 'online';
  }

  /**
   * 获取操作员，key为组ID,value为操作员数组
   */
  getOperatorMap() {
    return _operatorMap ? _operatorMap : new Map();
  }

  /**
   * 获取职员，key为组ID,value为职员数组
   */
  getEmployeeMap() {
    return _employeeMap ? _employeeMap : new Map();
  }

  /**
   * 获取摄像头，key为组ID,value为摄像头数组
   */
  getVideoMap() {
    return _videoMap ? _videoMap : new Map();
  }

  /**
   * 获取操作员信息
   */
  operatorquery() {
    return new Promise((resolve, reject) => {
      $.get('/operatorquery').then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
          // this.operatorInfo = res.eventdata;
        } else reject(res);
      });
    });
  }

  /**
   * 获取组
   * { parentid, groupid, beginIndex, count }
   * parentid为topgroup查询顶级组
   */
  group(form = {}) {
    return new Promise((resolve, reject) => {
      $.post('/group', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 获取操作员
   * { groupid, operatorid }
   * groupid = 'all'
   */
  operator(form = {}) {
    return new Promise((resolve, reject) => {
      $.post('/operator', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 操作员修改
   *
   */
  operatorMod(data) {
    return new Promise((resolve, reject) => {
      let obj = deepClone(data);
      obj['@id'] = '100000';
      obj['@type'] = 'OperatorMod';
      let form = {
        request: obj,
      };
      $.post('/dataflow', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 获取职员
   * { employeeid, groupid, beginIndex, count }
   */
  employee(form = {}) {
    return new Promise((resolve, reject) => {
      $.post('/employee', form).then(res => {
        if (res) {
          res = res.data;
          if (res.status === 200) {
            resolve(res);
          } else reject(res);
        } else {
          reject();
        }
      });
    });
  }

  /**
   * 职员修改
   *
   */
  employeeMod(data) {
    return new Promise((resolve, reject) => {
      let obj = deepClone(data);
      obj['@id'] = '100000';
      obj['@type'] = 'EmployeeMod';
      let form = {
        request: obj,
      };
      $.post('/dataflow', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 获取视频组
   * { parentid, groupid, beginIndex, count }
   * parentid为topgroup查询顶级组
   */
  videoGroup(form = {}) {
    return new Promise((resolve, reject) => {
      $.post('/videogroup', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 获取摄像头
   * { videoid, groupid, beginIndex, count }
   */
  video(form = {}) {
    return new Promise((resolve, reject) => {
      $.post('/video', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 摄像头修改
   */
  videoInfoMod(data) {
    return new Promise((resolve, reject) => {
      let obj = deepClone(data);
      obj['@id'] = '100000';
      obj['@type'] = 'VideoInfoMod';
      let form = {
        request: obj,
      };
      $.post('/dataflow', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 拆线
   * @param {String} calledDevice 用户号码
   */
  clearConnection(calledDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(calledDevice)) {
        reject('号码不能为空');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'ClearConnection',
          calledDevice: calledDevice,
        },
      };
      $.post('/clearconnection', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 单呼
   * @param {String} callingDevice 主叫号码
   * @param {String} calledDevice 被叫号码
   * @param {String} callType 呼叫类型，audio语音,video视频
   * @param {String} duplexMode 模式，full全双工，half半双工
   */
  makeCall({ callingDevice, calledDevice, callType, duplexMode }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(callingDevice, calledDevice)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MakeCall',
          callingDevice: callingDevice,
          called: { calledDevice: calledDevice },
          callType: callType ? callType : 'audio',
          duplexMode: duplexMode ? duplexMode : 'full',
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /*
   *简单呼叫转移
   *@parma activeDevice 通话的用户号码
   *@parma calledDevice 转接的用户号码
   */
  singleTransferCall({ activeDevice, calledDevice }) {
    return new Promise((resolve, reject) => {
      let form = {
        request: {
          '@id': '100000',
          '@type': 'SingleTransferCall',
          activeDevice: activeDevice,
          called: { "calledDevice": calledDevice },
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      })
        .catch(err => reject(err));
    });
  }

  /*
   *呼叫转接（需先咨询呼叫）
   *@parma heldDevice 被转接的用户号码
   *@parma activeDevice 转接的用户号码
   */
  transferCall({ heldDevice, activeDevice }) {
    return new Promise((resolve, reject) => {
      let form = {
        request: {
          '@id': '100000',
          '@type': 'TransferCall',
          heldDevice: heldDevice,
          activeDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      })
        .catch(err => reject(err));
    });
  }

  /*
  *咨询呼叫
  *@parma callingDevice 坐席
  *@parma activeDevice 被转接的用户号码
  *@parma  calledDevice 转接的用户号码
  *@parma  callType audio/video
  */
  consultCall({ callingDevice, activeDevice, calledDevice, callType }) {
    return new Promise((resolve, reject) => {
      let form = {
        request: {
          '@id': activeDevice,
          '@type': 'ConsultCall',
          "callingDevice": callingDevice,
          "activeDevice": activeDevice,
          "called": {
            "calledDevice": calledDevice,
            "userID": null
          },
          "callType": callType
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      })
        .catch(err => reject(err));
    });
  }

  /* 
  开班
  */
  agentWorkStart() {
    return new Promise((resolve, reject) => {
      let form = {
        "request": {
          "@id": "100000",
          "@type": "AgentWorkStart"
        }
      }
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /* 
  关班
  */
  gentWorkStop() {
    return new Promise((resolve, reject) => {
      let form = {
        "request": {
          "@id": "100000",
          "@type": "AgentWorkStop"
        }
      }
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }
  /*
   * 打开摄像头
   * @param {String} videoID 摄像头ID
   */
  openVideo1(videoID) {
    return new Promise((resolve, reject) => {
      if (!videoID) {
        return reject('摄像头ID不能为空');
      }
      $.post(`/openvideo`, { videoID })
        .then(res => {
          res = res.data;
          if (res.status === 200) {
            resolve(res);
          } else reject(res);
        })
        .catch(err => reject(err));
    });
  }

  /**
   * 打开摄像头
   * @param {String} videoID 视频ID
   */
  openVideo(videoID) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(videoID)) {
        reject('视频ID不能为空');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'OpenVideo',
          videoID: videoID,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 关闭摄像头
   * @param {String} videoID 视频ID
   * @param {String} flowID 流ID
   */
  closeVideo(videoID, flowID) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(videoID, videoID)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'CloseVideo',
          videoID: videoID,
          flowID: flowID,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 创建会议
   * @param {Object} form 表单
   * {meetName: "会议名称", meetNum,"会议号码", isAllowSpeak:"允许发言，yes/no", meetMode: "会议模式，video/audio"}
   */
  createMeet({
    meetName,
    meetNum,
    isAllowSpeak,
    meetMode,
    callinState,
    callinNum,
    callinPwd,
  }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetName, meetNum, isAllowSpeak, meetMode, callinState)) {
        reject('参数不全');
        return;
      }
      if (callinState === '1') {
        if (checkEmpty(callinNum, callinPwd)) {
          reject('呼入式会议，号码或密码不能为空');
          return;
        }
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'CreateMeet',
          meetName,
          meetNum,
          isAllowSpeak,
          meetMode,
          callinState,
          callinNum,
          callinPwd,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }
  /**
   * 修改会议
   * @param {Object} form 表单
   * {meetName: "会议名称", meetNum,"会议号码", isAllowSpeak:"允许发言，yes/no", meetID: "会议ID"}
   */
  modifyMeet({
    meetName,
    meetNum,
    isAllowSpeak,
    meetID,
    callinState,
    callinNum,
    callinPwd,
  }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetName, meetNum, isAllowSpeak, meetID)) {
        reject('参数不全');
        return;
      }
      if (callinState === '1') {
        if (checkEmpty(callinNum, callinPwd)) {
          reject('呼入式会议，号码或密码不能为空');
          return;
        }
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'ModifyMeet',
          meetName,
          meetNum,
          isAllowSpeak,
          meetID,
          callinState,
          callinNum,
          callinPwd,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /*
   * 删除会议
   * @param {String} meetID 会议ID
   */
  delMeet(meetID) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID)) {
        reject('会议ID不能为空');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'EndMeet',
          meetID: meetID,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 踢出成员
   * @param {String} meetID 会议ID
   * @param {String} activeDevice 号码，为空时踢出所有人，即关闭会场
   */
  meetKick(meetID, activeDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetKick',
          meetID: meetID,
          activeDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 单独通话
   * @param {String} meetID 会议ID
   * @param {String} callingDevice  主叫号码
   * @param {String} activeDevice 被叫号码
   */
  meetSingleTalk(meetID, callingDevice, activeDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, callingDevice, activeDevice)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetSingleTalk',
          meetID: meetID,
          callingDevice: callingDevice,
          activeDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 回到会场
   * @param {String} meetID 会议ID
   * @param {String} activeDevice 号码
   */
  meetBack(meetID, activeDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, activeDevice)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetBack',
          meetID: meetID,
          activeDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 会议录音
   * @param {String} meetID 会议ID
   * @param {String} isRecord 是否录音 yes/no
   */
  meetRecord(meetID, isRecord) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, isRecord)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetRecord',
          meetID: meetID,
          isRecord: isRecord,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 会议锁定
   * @param {String} meetID 会议ID
   * @param {String} isLocked 是否锁定 yes/no
   */
  meetLock(meetID, isLocked) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, isLocked)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetLock',
          meetID: meetID,
          isLocked: isLocked,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 会议允许发言
   * @param {String} meetID 会议ID
   * @param {String} activeDevice 号码，为空时永许所有发言
   */
  meetAllowSpeak(meetID, activeDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetAllowSpeak',
          meetID: meetID,
          activeDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 会议禁止发言
   * @param {String} meetID 会议ID
   * @param {String} activeDevice 号码，为空时禁止所有发言
   */
  meetBanSpeak(meetID, activeDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetBanSpeak',
          meetID: meetID,
          activeDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 会议广播
   * @param {String} meetID 会议ID
   * @param {String} isBroadcast 是否广播 yes/no
   * @param {String} fileName 文件名
   */
  meetBroadcast(meetID, isBroadcast, fileName) {
    return new Promise((resolve, reject) => {
      let empty =
        isBroadcast === 'yes'
          ? checkEmpty(meetID, isBroadcast, fileName)
          : checkEmpty(meetID, isBroadcast);
      if (empty) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'MeetBroadcast',
          meetID: meetID,
          isBroadcast: isBroadcast,
          fileName: fileName,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 获取会议列表
   */
  getMeetingList() {
    return new Promise((resolve, reject) => {
      $.get('/meetinfo')
        .then(res => {
          if (res.data) {
            res = res.data;
            resolve(res);
          } else {
            reject();
          }
        })
        .catch(err => {
          reject(err);
        });
    });
  }

  /**
   * 获取会议成员
   * @param {String} meetID 会议ID
   */
  getMeetingMember(meetID) {
    return new Promise((resolve, reject) => {
      if (!meetID) {
        return reject('会议ID不能为空');
      }
      $.post('/meetmember', { meetID }).then(res => {
        res = res.data;
        if (res.msg !== 'fail') {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 对讲编组
   * @param {String} callingDevice 主叫号码
   * @param {Array} called 被叫号码,数组
   */
  selectCallEx({ callingDevice, called, callingMode, Time }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(callingDevice, called, callingMode)) {
        return reject('参数不全');
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'SelectCallEx',
          callingDevice: callingDevice,
          called: called,
          Time: Time,
          callingMode: callingMode,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 会议呼叫（选呼）
   * @param {String} meetID 会议ID
   * @param {Array} calledDevices 被叫号码,数组
   * @param {String} callingDevice 主叫号码
   */
  meetingCall(meetID, calledDevices = [], callingDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, callingDevice) || calledDevices.length === 0) {
        reject('参数不全');
        return;
      }
      let form;
      let called = [];
      calledDevices.forEach(item => {
        if (item)
          called.push({
            calledDevice: item,
          });
      });
      form = {
        request: {
          '@id': '100000',
          '@type': 'SelectCall',
          callMode: 'parallel',
          meetID: meetID,
          callingDevice: callingDevice,
          called: called,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 组呼
   * @param {String} meetID 会议ID
   * @param {Array} groupID 组ID
   * @param {String} callingDevice 主叫号码
   * @param {String} callMode 呼叫模式
   */
  groupCall(meetID, groupID, callingDevice, callMode = 'parallel') {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, groupID, callingDevice)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'GroupCall',
          callingDevice: callingDevice,
          groupID: groupID,
          meetID: meetID,
          callMode: callMode,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /*
   * 获取视频通话图像
   * @param {String} userTel 用户号码
   */
  userVideo(userTel) {
    return new Promise((resolve, reject) => {
      if (!userTel) {
        return reject('用户号码不能为空');
      }
      $.post(`/user_video`, { userTel })
        .then(res => {
          res = res.data;
          if (res.status === 200) {
            resolve(res);
          } else reject(res);
        })
        .catch(err => reject(err));
    });
  }

  /**
   * 获取流地址
   * @param {String} activeDevice 号码
   */
  getVideoUrl(activeDevice) {
    return new Promise((resolve, reject) => {
      if (!activeDevice) {
        reject('号码不能为空');
      }
      let form = {
        request: {
          '@id': '32',
          '@type': 'GetVideoRtspUrl',
          calledDevice: activeDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 混码
   * @param {String} meetID 会议ID
   * @param {Integer} mixType 会商输出几分屏 1，2，4，6，8，9
   * @param {Array} sources 视频源
   * @param {String} videoType 视频类型，默认720P
   */
  setMeetVideoMix({ meetID, mixType, sources, videoType }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(meetID, mixType)) {
        reject('参数不全');
        return;
      }
      while (mixType > sources.length) {
        sources.push({});
      }
      if (mixType < sources.length) {
        sources = sources.slice(mixType);
      }
      let form = {
        request: {
          '@id': '33',
          '@type': 'SetMeetVideoMix',
          mixType: mixType,
          videoType: videoType ? videoType : '720P',
          meetID: meetID,
          source: sources,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          setTimeout(() => {
            $.post('/makecall', form).then(res2 => { });
          }, 200);

          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 视频分发
   * @param {String} calledDevice 用户号码
   * @param {String} videoID 视频ID
   * @param {String} flowID 流ID
   * @param {Array} target 分发目标
   */
  videoDispense({ calledDevice, videoID, flowID, target, mesg_id }) {
    return new Promise((resolve, reject) => {
      if (
        (!calledDevice && !videoID && !flowID) ||
        !target ||
        target.length === 0
      ) {
        reject('参数不全');
      }
      let form = {
        request: {
          '@id': mesg_id,
          '@type': 'StartVideoDispense',
          calledDevice: calledDevice,
          videoID: videoID || '',
          flowID: flowID,
          target,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 停止视频分发
   * @param {String} flowID 分发任务ID
   * @param {String} calledDevice 用户号码
   * @param {String} videoID 视频ID
   * @param {Array} target 分发目标
   */
  stopVideoDispense({ flowID, calledDevice, videoID, target }) {
    return new Promise((resolve, reject) => {
      if (!flowID || (!calledDevice && !videoID)) {
        reject('参数不全');
      }
      let srcs = [];
      if (target) {
        srcs = target.map(src => {
          return { dstDevice: src };
        });
      }
      let form = {
        request: {
          '@id': '33',
          '@type': 'StopVideoDispense',
          flowID: flowID,
          calledDevice: calledDevice,
          videoID: videoID,
          target: srcs,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 获取语音文件
   */
  voiceFileList() {
    return new Promise((resolve, reject) => {
      $.get('/fileflow/filelist').then(res => {
        res = res.data;
        if (res.msg === 'success') {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 删除文件
   * @param {String} fileid 文件id
   */
  deleteFile(fileid) {
    return new Promise((resolve, reject) => {
      $.delete(`/fileflow/${fileid}`)
        .then(res => {
          res = res.data;
          if (res.msg === 'success') {
            resolve(res);
          } else reject(res);
        })
        .catch(err => {
          reject(err);
        });
    });
  }

  /**
   * 试听
   * @param {String} callingDevice 播放号码
   * @param {String} voiceID 文件ID
   * @param {String} voiceName 文件名
   */
  voiceFileListen(callingDevice, voiceID, voiceName) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(callingDevice, voiceID, voiceName)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'VoiceFileListen',
          voiceID: voiceID,
          callingDevice: callingDevice,
          VoiceName: voiceName,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 停止试听
   * @param {String} callingDevice 播放号码
   */
  voiceFileListenStop(callingDevice) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(callingDevice)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'VoiceFileListenStop',
          callingDevice: callingDevice,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 修改语音文件
   * @param {String} voiceID 文件ID
   * @param {String} voiceName 文件名称
   * @param {String} remark 备注
   */
  voiceFileMod(voiceID, voiceName, orifilename, remark) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(voiceID, voiceName)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'VoiceFileMod',
          voiceID: voiceID,
          voiceName: voiceName,
          orifilename: orifilename,
          remark: remark,
          description: voiceName,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 传真文字存储
   * @param {String} content 文字内容
   */
  faxContent(content) {
    return new Promise((resolve, reject) => {
      if (!content) {
        reject('文字不能为空');
        return;
      }
      $.post('/faxcontent', { content }).then(res => {
        res = res.data;
        if (res.msg === 'success') {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 传真发送
   * @param {String} faxContent 文字内容
   * @param {String} faxRealFileName 文件名
   * @param {String} faxFileSize 文件大小
   * @param {Array} faxContacts 收件人
   */
  faxSend({ faxContent, faxRealFileName, faxFileSize, faxContacts, remark }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(faxContacts)) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'FaxSend',
          faxContent: faxContent,
          faxRealFileName: faxRealFileName,
          faxFileSize: faxFileSize,
          faxContacts: faxContacts,
          remark: remark,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 传真查询
   * @param {Integer} pageNum 页数
   * @param {Integer} pageSize 页大小
   * @param {String} faxState 状态  0所有，1发送成功send succe，2发送失败send fail  ，3已读read，4未读unread
   * @param {String} fileName 文件名
   * @param {String} direct 方向 send发件箱 recv收件箱
   * @param {String} telNum 号码
   * @param {Array} daterange 时间范围，length=2, daterange[0]为开始时间，daterange[1]为结束时间；格式20200520151628
   */
  faxList({
    pageNum,
    pageSize,
    direct,
    faxState,
    fileName,
    telNum,
    daterange,
  }) {
    return new Promise((resolve, reject) => {
      let form = {
        beginIndex: (pageNum - 1) * pageSize,
        count: pageSize,
        faxState: faxState,
        fileName: fileName,
        direct: direct,
        telNum: telNum,
        beginTime: daterange[0],
        endTime: daterange[1],
      };
      $.post('/faxlist', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 传真查询
   * @param {String} faxID 传真ID
   */
  faxDelete(faxID) {
    return new Promise((resolve, reject) => {
      if (!faxID) {
        reject('参数不全');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'FaxDelete',
          faxContacts: null,
          faxGroupID: null,
          faxID: faxID,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 传真已读
   * @param {String} faxID 传真ID
   * @param {String} faxContacts 传真联系人号码
   */
  faxRead(faxID, faxContacts) {
    return new Promise((resolve, reject) => {
      if (!faxContacts) {
        reject('传真联系人不能为空');
        return;
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'FaxRead',
          faxContacts,
          faxID,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 传真文件下载
   * @param {String} filename 文件名
   */
  async faxfile(filename, realFileName) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(filename)) {
        return reject('文件名不能为空');
      }
      $.get(`/faxfile/${filename}`, { responseType: 'blob' }).then(res => {
        if (!res) {
          return reject('下载文件失败');
        }
        if (res.config.responseType === 'blob') {
          if (
            res.data.type === 'text/html' ||
            res.data.type === 'application/json'
          ) {
            const reader = new FileReader();
            reader.onload = () => {
              if (reader.result === 'The file is not exist') {
                msgError('文件不存在');
              } else {
                msgError(reader.result);
              }
              return reject(reader.result);
            };
            reader.readAsText(res.data);
          } else {
            FileSaver.saveAs(res.data, decodeURI(realFileName || filename));
            return resolve(res);
          }
        }
      });
    });
  }

  /**
   * 广播呼叫
   * @param {*} param0
   */
  broadcastCall({ callingDevice, called, callMode, time, fileName, callLoop }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(called, callMode, callLoop)) {
        return reject('参数不全');
      }
      if (callMode === 'manual' && !called) {
        return reject('人工语音时，主叫号码不能为空');
      }
      if (callMode !== 'manual' && !fileName) {
        return reject('文件不能为空');
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'BroadcastCall',
          callingDevice,
          called,
          callMode,
          time,
          fileName,
          callLoop,
        },
      };
      $.post('/makecall', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 生成tts文件
   * @param {String} content 文字内容
   */
  genarateTts(content) {
    return new Promise((resolve, reject) => {
      if (!content.trim()) {
        return reject('文字内容不能为空');
      }
      $({
        url: `/ttsfile`,
        params: { content: content },
        method: 'get',
      }).then(res => {
        res = res.data;
        if (res.msg == 'success') {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 发送短信
   * @param {*} param0
   */
  smsSend({
    smsType,
    smsContacts,
    smsFormat,
    smsContent,
    smsFileName,
    smsRealFileName,
    smsFileSize,
  }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(smsType, smsContacts, smsFormat)) {
        return reject('参数不全');
      }
      if (!smsContent && !smsFileName) {
        return reject('短信内容或附件为空');
      }
      let form = {
        request: {
          '@id': '100000',
          '@type': 'SmsSend',
          smsType,
          smsContacts,
          smsFormat,
          smsContent,
          smsFileName,
          smsRealFileName,
          smsFileSize,
        },
      };
      $.post('/smsflow', form).then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 短信文件下载
   * @param {String} filename 文件名
   */
  smsfile(filename) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(filename)) {
        reject('文件名不能为空');
        return;
      }
      $.get(`/smsfile/${filename}`, { responseType: 'blob' }).then(res => {
        if (!res) {
          reject('下载文件失败');
          return;
        }
        const blob = new Blob([res.data], {
          type:
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
        });
        // for IE
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
          window.navigator.msSaveOrOpenBlob(blob, filename);
        } else {
          const downloadElement = document.createElement('a');
          const href = window.URL.createObjectURL(blob);
          downloadElement.style.display = 'none';
          downloadElement.href = href;
          downloadElement.download = filename; //下载后文件名
          document.body.appendChild(downloadElement);
          downloadElement.click(); //点击下载
          document.body.removeChild(downloadElement); //下载完成移除元素
          window.URL.revokeObjectURL(href); //释放掉blob对象
        }
      });
    });
  }

  /**
   * 位置订阅
   * @param {String} device GPS编号（号码）
   */
  subscribeLocation(device = 'all') {
    return new Promise((resolve, reject) => {
      if (checkEmpty(device)) {
        return reject('GPS编号不能为空');
      }
      $.get(`/location/subscribe?device=${device}`)
        .then(res => {
          res = res.data;
          if (res.status === 200) {
            resolve(res);
          } else reject(res);
        })
        .catch(err => reject(err));
    });
  }

  /**
   * 位置查询
   * @param {String} device GPS编号（号码）
   */
  location(device) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(device)) {
        return reject('GPS编号不能为空');
      }
      $.get(`/location?device=${device}`)
        .then(res => {
          res = res.data;
          console.log('location', res);
          if (res.status === 200) {
            resolve(res);
          } else reject(res);
        })
        .catch(err => reject(err));
    });
  }

  /**
   * 历史定位查询
   *{ deviceCode, start, end, pageSize, pageNum }
   */
  historyLocation({ deviceCode, start, end, pageSize, pageNum }) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(deviceCode, start, end, pageSize, pageNum)) {
        reject('参数不全');
        return;
      }
      let form = {
        deviceCode,
        start,
        end,
        count: pageSize,
        beginIndex: (pageNum - 1) * pageSize,
      };
      $.post('/historylocation', form).then(res => {
        res = res.data;
        console.log('historyLocation', res);
        if (res.result === 'sucess') {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 登录
   * @param {*} username 用户名
   * @param {*} password 密码
   * @param {*} isForced 是否强制登录 true为强制登录
   */
  login(username, password, isForced) {
    return new Promise((resolve, reject) => {
      if (!username || !password) {
        reject('用户名或密码不能为空');
      }
      // 登录请求参数
      let data = {
        request: {
          '@id': '10000',
          '@type': 'UserLogin',
          userName: username,
          userPwd: password,
        },
      };
      // 强制登出
      if (isForced) {
        this.forcelogout(username, password).then(res => {
          $.post('/login', data).then(res => {
            res = res.data;
            if (res.msg === 'fail') {
              reject(res);
            } else if (res.status === 200) {
              // 保存cookie,其他请求的header需要携带该值
              this.setToken(res.tokensign);
              postLogin.call(this);
              resolve(res);
            } else {
              reject(res);
            }
          });
        });
      } else {
        this.forcelogout(username, password).then(res => {
          $.post('/login', data).then(res => {
            res = res.data;
            if (res.msg === 'fail') {
              reject(res);
            } else if (res.status === 200) {
              // 保存cookie,其他请求的header需要携带该值
              this.setToken(res.tokensign);
              postLogin.call(this);
              resolve(res);
            } else {
              reject(res);
            }
          });
        });
      }
    });
  }

  /**
   * 通过号码获取职员
   * @param {String} tel 电话号码
   */
  getEmloyeeByTel(tel) {
    return _employeeTelMap.get(tel);
  }

  /**
   * 通过号码获取用户
   * @param {String} tel 电话号码
   */
  getUserInfoByTel(tel) {
    return _operatorTelMap.get(tel) || _employeeTelMap.get(tel);
  }

  /**
   * 获取所有组-树型结构
   */
  getTreeGroup() {
    return new Promise((resolve, reject) => {
      this.group()
        .then(res => {
          let arr = res.data.organizations;
          let nodeMap = new Map(
            arr.map(obj => {
              let pid = obj.parentID;
              let node = { obj };
              if (!pid) node.nid = `${node.id}`;
              node.id = obj.groupID;
              node.parentID = pid;
              node.label = obj.groupName;
              node.children = [];
              node.type = 'group';
              return [obj.groupID, node];
            })
          );
          // 树结构
          let treeMap = new Map();
          for (let key of nodeMap.keys()) {
            let node = nodeMap.get(key);
            let pid = node.parentID;
            if (pid === '' && !treeMap.has(pid)) {
              treeMap.set(key, node);
            } else {
              const parentNode = nodeMap.get(pid);
              node.nid = this.resolveNid(nodeMap, node, parentNode);
              if (parentNode) parentNode.children.push(node);
            }
          }
          resolve([...treeMap.values()]);
        })
        .catch(err => {
          reject(err);
        });
    });
  }

  /**
   * 获取节点nid, 由每个节点的id与|相加，用来保证节点key唯一
   * @param {Map} map
   * @param {Object} node 当前节点
   * @param {Object} pNode 父节点，当父节点nid不为空时认为找到
   */
  resolveNid(map, node, pNode) {
    if (pNode.nid) {
      return `${pNode.nid}|${node.id}`;
    }
    if (!pNode.parentID) {
      pNode.nid = pNode.id;
      return `${pNode.nid}|${node.id}`;
    }
    // 递归
    const n = map.get(pNode.parentID);
    pNode.nid = this.resolveNid(map, pNode, n);
    return `${pNode.nid}|${node.id}`;
  }

  /**
   * 获取所有摄像头-树形结构(含组织结构)
   */
  treeGroupAndVideo() {
    return new Promise((resolve, reject) => {
      $.all([this.videoGroup(), this.video()])
        .then(
          $.spread((groupRes, videoRes) => {
            let groups = groupRes.data.organizations;
            //排序
            groups.sort(compare('order'));
            let nodeMap = new Map(
              groups.map(obj => {
                let pid = obj.parentID;
                let node = { obj };
                node.id = obj.videoGroupID;
                node.parentID = pid;
                if (!pid) node.nid = `${node.id}`;
                node.label = obj.groupName;
                node.children = [];
                node.type = 'group';
                return [obj.videoGroupID, node];
              })
            );
            if (nodeMap.size === 0) {
              return resolve([]);
            }
            // 树结构
            let treeMap = new Map();
            for (let key of nodeMap.keys()) {
              let node = nodeMap.get(key);
              let pid = node.parentID;
              if ((pid === '' || pid === null) && !treeMap.has(pid)) {
                treeMap.set(key, node);
              } else {
                const parentNode = nodeMap.get(pid);
                node.nid = this.resolveNid(nodeMap, node, parentNode);
                if (parentNode) parentNode.children.push(node);
              }
            }

            // 摄像头
            let cameraList = !videoRes.data.cameras
              ? []
              : videoRes.data.cameras;
            let videoList = [];
            for (let i = 0, length = cameraList.length; i < length; i++) {
              let obj = cameraList[i];
              let pidObjs = obj.group;
              for (const pidObj of pidObjs) {
                const pid = pidObj.groupID;
                let node = { obj };
                node.id = obj.videoID;
                node.parentID = pid;
                node.label = obj.videoName;
                node.type = 'video';
                node.status = obj.status;
                node.orderNO = pidObj.orderNO;
                videoList.push(node);
              }
            }
            //排序
            videoList.sort(compare('orderNO'));
            videoList.forEach(video => {
              const pid = video.parentID;
              let pNode = nodeMap.get(pid);
              if (pNode) {
                video.nid = `${pNode.nid}|${video.id}`;
                video.groupName = pNode.obj.groupName;
                pNode.children.push(video);
              }
            });
            resolve([...treeMap.values()]);
          })
        )
        .catch(err => {
          reject(err);
        });
    });
  }

  /**
   * 获取所有联系人-树形结构(含组织结构)
   * @param {Boolean} divided 职员或操作员有多个号码时是否需要分隔成多个对象显示 false不分
   */
  treeGroupAndContact(divided = false) {
    return new Promise((resolve, reject) => {
      $.all([this.group(), this.operator({ groupid: 'all' }), this.employee()])
        .then(
          $.spread((groupRes, operRes, empRes) => {
            // 组
            let groups = groupRes.data.organizations;
            // 用Map保存，方便树结构
            let nodeMap = new Map(
              groups.map(obj => {
                let pid = obj.parentID;
                let node = { obj };
                node.id = obj.groupID;
                node.parentID = pid;
                if (!pid) node.nid = `${node.id}`;
                node.label = obj.groupName;
                node.children = [];
                node.type = 'group';
                return [obj.groupID, node];
              })
            );
            if (nodeMap.size === 0) {
              return resolve([]);
            }
            // 树结构
            let treeMap = new Map();
            for (let key of nodeMap.keys()) {
              let node = nodeMap.get(key);
              let pid = node.parentID;
              if (pid === '' && !treeMap.has(pid)) {
                treeMap.set(key, node);
              } else {
                const parentNode = nodeMap.get(pid);
                node.nid = this.resolveNid(nodeMap, node, parentNode);
                if (parentNode) parentNode.children.push(node);
              }
            }

            // 操作员
            let operatorList = operRes.data.operator;
            for (let i = 0; i < operatorList.length; i++) {
              const obj = operatorList[i];
              if (obj.mainTel && obj.mainTelType === 'phone')
                obj.defaultNo = obj.mainTel;
              else if (obj.viceTel && obj.viceTelType === 'phone')
                obj.defaultNo = obj.viceTel;
              else obj.defaultNo = '';
              let pid = obj.groupID;
              let node = { obj };
              node.id = obj.operatorID;
              node.parentID = pid;
              node.label = obj.realName;
              node.type = 'operator';
              let pNode = nodeMap.get(pid);
              if (pNode) {
                node.nid = `${pNode.nid}|${node.id}`;
                obj.groupName = pNode.obj.groupName;
                pNode.children.push(node);
              }
            }
            // 职员
            let employeeList = !empRes.data.employee
              ? []
              : empRes.data.employee;
            for (let i = 0; i < employeeList.length; i++) {
              const obj = employeeList[i];
              let pidObjs = obj.group;
              for (const pidObj of pidObjs) {
                const pid = pidObj.groupID;
                let node = { obj };
                node.id = obj.employeeID;
                node.parentID = pid;
                node.label = obj.realName;
                node.type = 'employee';
                let pNode = nodeMap.get(pid);
                if (pNode) {
                  node.nid = `${pNode.nid}|${node.id}`;
                  obj.groupName = pNode.obj.groupName;
                  pNode.children.push(node);
                }
              }
            }

            resolve([...treeMap.values()]);
          })
        )
        .catch(err => {
          reject(err);
        });
    });
  }

  /**
   * 获取职员
   * @param {String} groupid 组id
   * @param {String} type 组类型
   */
  getContactByGroup(groupid, type) {
    return new Promise((resolve, reject) => {
      if (type === 'dispatchgroup') {
        this.operator({ groupid })
          .then(res => {
            if (res.status === 200) {
              // 操作员
              resolve(res.data);
            } else {
              reject(res);
            }
          })
          .catch(err => {
            reject(err);
          });
      } else {
        this.employee({ groupid })
          .then(res => {
            res = res.data;
            resolve(res);
          })
          .catch(err => {
            reject(err);
          });
      }
    });
  }

  /**
   * 获取权限组
   * @param {String} groupid 组id
   * @param {String} type 组类型
   */
  getAllAuthGroup() {
    return new Promise((resolve, reject) => {
      $.post('/rightgrouprelation ').then(res => {
        res = res.data;
        if (res.status === 200) {
          resolve(res);
        } else reject(res);
      });
    });
  }

  /**
   * 登出
   */
  logout() {
    return new Promise((resolve, reject) => {
      if (this.getToken()) {
        $.get('/userlogout').then(res => {
          if (res.status === 200) {
            resolve(res);
          } else {
            reject(res);
          }
        });
      } else {
        resolve({ status: 200 });
      }
    });
  }

  /**
   * 强制登出
   * @param {*} username 用户名
   * @param {*} password 密码
   */
  forcelogout(username, password) {
    return new Promise((resolve, reject) => {
      if (checkEmpty(username, password)) {
        reject('参数不全');
        return;
      }
      $.post('/forcelogout', { username: username, userpwd: password }).then(
        res => {
          res = res.data;
          if (res.status === 200) {
            resolve(res);
          } else {
            reject(res);
          }
        }
      );
    });
  }

  /**
   * 获取主叫号码
   */
  getCallingDevice() {
    if (!this.operatorInfo) {
      // throw new Error('操作员不存在');
      return [];
    }
    let callings = [];
    if (
      this.operatorInfo.mainTel &&
      this.operatorInfo.mainTelType === 'phone'
    ) {
      callings.push(this.operatorInfo.mainTel);
    }
    if (this.operatorInfo.viceTel && this.operatorInfo.viceTel === 'phone') {
      callings.push(this.operatorInfo.viceTel);
    }
    return callings;
  }

  /**
   * 获取手咪主叫号码
   */
  getHandMicroPhone() {
    if (!this.operatorInfo) {
      // throw new Error('操作员不存在');
      return [];
    }
    let callings = [];
    if (
      this.operatorInfo.mainTel &&
      this.operatorInfo.mainTelType === 'hand_microphone'
    ) {
      callings.push(this.operatorInfo.mainTel);
    }
    if (
      this.operatorInfo.viceTel &&
      this.operatorInfo.viceTelType === 'hand_microphone'
    ) {
      callings.push(this.operatorInfo.viceTel);
    }
    return callings;
  }

  /**
   * 设置回调函数
   * @param {Function} event
   */
  setEvent(event) {
    this.event = event;
  }

  /**
   * 设置回调函数
   * @param {Function} event
   */
  setEventMore(eventMore) {
    this.eventMore = eventMore;
  }

  /**
   * 返回服务器的地址
   */
  idispatchServer() {
    return $.defaults.baseURL;
    // return 'http://10.20.50.207:10064/idispatcha';//
    // return 'http://localhost:8099/aaa';
  }

  /**
   * token
   * @param {*} token  token
   */
  setToken(token) {
    sessionStorage.setItem('tokenSign', token);
  }
  getToken() {
    return sessionStorage.getItem('tokenSign');
  }
  removeToken() {
    sessionStorage.removeItem('tokenSign');
  }

  /**
   * 编辑电子围栏
   * @param {String} fenceName 名称
   * @param {Array} points 点位 {pos_x,pos_y}
   * @param {Array} users 点位 {userName,userID,userTel}
   */
  editfence(form) {
    return new Promise((resolve, reject) => {
      if (form.fenceID) {
        $.put('/electronicfence', form).then(res => {
          res = res.data;
          if (res.result === 'succ') {
            resolve(res);
          } else {
            reject(res);
          }
        });
      } else {
        $.post('/electronicfence', form).then(res => {
          res = res.data;
          if (res.result === 'succ') {
            resolve(res);
          } else {
            reject(res);
          }
        });
      }
    });
  }

  /**
   * 查询电子围栏
   */
  electronicfence() {
    return new Promise((resolve, reject) => {
      $.get('/electronicfence').then(res => {
        res = res.data;
        if (Array.isArray(res)) {
          resolve(res);
        } else {
          reject(res);
        }
      });
    });
  }

  /**
   * 删除电子围栏
   */
  deleteFence(fenceID) {
    return new Promise((resolve, reject) => {
      $({
        url: '/electronicfence',
        method: 'delete',
        data: { fenceID },
      }).then(res => {
        res = res.data;
        if (res.result === 'succ') {
          resolve(res);
        } else {
          reject(res);
        }
      });
    });
  }

  /**
   * 查询电子围栏告警记录
   */
  fenceAlarm(form) {
    return new Promise((resolve, reject) => {
      form.beginIndex = (form.pageNum - 1) * form.pageSize;
      form.count = form.pageSize;
      $({
        url: '/fencealarm',
        method: 'post',
        data: form,
      }).then(res => {
        res = res.data;
        if (res.result && res.result === 'fail') {
          reject(res);
        } else {
          resolve(res);
        }
      });
    });
  }
  /**
   * 删除电子围栏告警记录
   * @param {Array} alarmIDs 要删除的id数组
   * @param {String} fenceID 要删除的fenceID
   */
  deleteFenceAlarm({ alarmIDs, fenceID }) {
    return new Promise((resolve, reject) => {
      $({
        url: '/fencealarm',
        method: 'delete',
        data: { alarmIDs, fenceID },
      }).then(res => {
        res = res.data;
        if (res.result === 'succ') {
          resolve(res);
        } else {
          reject(res);
        }
      });
    });
  }
  /**
   * 导出电子围栏告警记录
   * @param {Array} alarmIDs 要导出的id数组
   * @param {String} fenceID 要导出的fenceID
   */
  exportFenceAlarm({ alarmIDs, fenceID }) {
    return new Promise((resolve, reject) => {
      $.get('/fencealarm', { alarmIDs, fenceID }).then(res => {
        res = res.data;
        if (Array.isArray(res)) {
          resolve(res);
        } else {
          reject(res);
        }
      });
    });
  }
}

function postConstruct(options) { }

/**
 * 登录后置操作，初始化缓存，轮询等
 */
export function postLogin() {
  if (this.isPoll) poll.call(this);
  // 开启轮询
  else heartbeat.call(this); // 心跳，保活
  getOperator.call(this); // 获取操作员信息
}

/**
 * 获取操作员信息
 */
function getOperator() {
  this.operatorquery()
    .then(res => {
      this.operatorInfo = res.eventdata;
    })
    .catch(err => {
      this.operatorInfo = null;
    });
}

/**
 * 轮询
 */
function poll() {
  // console.log('poll time', new Date().toLocaleTimeString());
  if (_pollTimer) clearTimeout(_pollTimer);
  let interval = this.pollInterval;
  const self = this;
  $.get('/poll')
    .then(res => {
      if (_pollTimer) clearTimeout(_pollTimer);
      _pollTimer = setTimeout(() => {
        // console.log('poll res next');
        if (_pollTimer) clearTimeout(_pollTimer);
        poll.call(self);
      }, interval);

      // console.log('poll res');
      res = res.data;
      if (res.msg === 'fail' && res.reason === 'user_logout') {
        destroySDK.call(this);
        return;
      }
      if (res.status === 200) {
        try {
          if (res.count > 0) {
            //处理轮询结果
            // console.log('SDK.poll', res.count, JSON.stringify(res.msg));
            for (const e of res.msg) {
              // console.log('SDK.pollItem', e.type, JSON.stringify(e));
              switch (e.type) {
                case 'MeetStatusEvent':
                  break;
                case 'NewSms':
                  self.haveNewSms = true;
                  self.haveNewSmsKeepFresh = true;
                  //创建提示框
                  window.handleCreatSmsNotification();
                  let menuList = JSON.parse(sessionStorage.getItem('menuList'));
                  menuList.forEach(element => {
                    if (element.LoadPath == '/sms') {
                      element.newInfoCount = element.newInfoCount + 1;
                    }
                  });
                  sessionStorage.setItem('menuList', JSON.stringify(menuList));
                  store.dispatch('navEvent'); // vuex缓存
                  break;
                case 'UserStatus':
                  _userStatusMap.set(e.deviceTel, e); // 号码状态
                  if (
                    e.deviceStatus == 'talk' &&
                    e.deviceTel == this.operatorInfo.mainTel
                  ) {
                    //打入当前调度台电话
                    sessionStorage.setItem('linkDevice', e.linkDevice);
                  }
                  break;
                case 'NewFax':
                  Notification({
                    title: '提示',
                    showClose: true,
                    type: 'success',
                    message: '您有一条新的传真,请注意查收',
                    duration: 3 * 1000,
                  });
                  store.dispatch('navEvent'); // vuex缓存
                  break;
                //分发视频到web操作员
                case 'VideoDispenseEvent':
                  Notification({
                    title: '提示',
                    showClose: true,
                    type: 'success',
                    message: '收到分发视频,请注意查收',
                    duration: 3000,
                  });
                  let tableData =
                    sessionStorage.getItem('tableData') == 'null' ||
                      sessionStorage.getItem('tableData') == null
                      ? [{}, {}, {}, {}]
                      : JSON.parse(sessionStorage.getItem('tableData'));
                  let playSet = {
                    rtspFlag: true,
                    isCamera: true,
                    src: e.eventdata.rtspUrl,
                    id: e.eventdata.videoID,
                    flowID: e.eventdata.flowID,
                    type: 'common',
                  };
                  for (let i = 0; i < tableData.length; i++) {
                    let obj = tableData[i];
                    if (JSON.stringify(obj) == '{}') {
                      tableData[i] = playSet;
                      sessionStorage.setItem(
                        'tableData',
                        JSON.stringify(tableData)
                      );
                      break;
                    }
                  }
                  break;
                default:
                  break;
              }
              store.dispatch('cacheEvent', e); // vuex缓存
              if (this.event) this.event(e); // 回调
              if (this.eventMore) this.eventMore(e); // 回调
            }
          }
        } catch (error) {
          console.log('==========pollERROR=========' + error);
        }
      }
    })
    .catch(err => {
      if (_pollTimer) clearTimeout(_pollTimer);
      console.log('poll error', err);
    });
}

/**
 * 心跳 保活
 */
function heartbeat() {
  $.get('/keepconnect').then(res => {
    res = res.data;
    if (res.msg === 'fail' && res.reason === 'user_logout') {
      destroySDK.call(this);
    } else {
      _heartbeatTimer = setTimeout(() => {
        heartbeat();
      }, _heartbeatInterval);
    }
  });
}

/**
 * 判段参数是否为空
 * @param  {...any} args 参数组
 */
function checkEmpty(...args) {
  if (args.length > 0) {
    for (const item of args) {
      if (Array.isArray(item)) {
        let isEmpty = true;
        for (const i of item) {
          if (i) {
            isEmpty = false;
            break;
          }
        }
        if (isEmpty) return true;
      } else if (typeof item === 'boolean' || Number.isFinite(item)) {
        continue;
      } else if (!item) {
        return true;
      }
    }
  }
  return false;
}

/**
 * 销毁
 */
export function destroySDK() {
  clearTimeout(_heartbeatTimer);
  clearTimeout(_pollTimer);
  window.SDK = undefined;
}

export const initSDK = () => {
  if (!window.SDK) {
    window.SDK = new SDK();
  }
  if (window.SDK.getToken()) {
    postLogin.call(window.SDK);
  }
};

(function () {
  initSDK();
})();

// export default initSDK;
